
	
	<p><span class='wp_keywordlink'><a href="http://blog.linuxeye.com/tag/CentOS" title="Linux" target="_blank">CentOS</a></span> 7 使用systemd替换了SysV。Systemd目的是要取代Unix时代以来一直在使用的init系统，兼容SysV和LSB的启动脚本，而且够在进程启动过程中更有效地引导加载服务。</p>
<p>systemd的特性有：</p>
<ul>
<li>
		支持并行化任务
	</li>
<li>
		同时采用socket式与D-Bus总线式激活服务；
	</li>
<li>
		按需启动守护进程（daemon）；
	</li>
<li>
		利用 <span class='wp_keywordlink'><a href="http://www.linuxeye.com" title="Linux" target="_blank">Linux</a></span> 的 cgroups 监视进程；
	</li>
<li>
		支持快照和系统恢复；
	</li>
<li>
		维护挂载点和自动挂载点；
	</li>
<li>
		各服务间基于依赖关系进行精密控制。
	</li>
</ul>
<p>
<span style="color:#006600;"><strong>systemd基本工具</strong></span><br />
检视和控制systemd的主要命令是systemctl。该命令可用于查看系统状态和管理系统及服务。详见man 1 systemctl。</p>
<blockquote><p>
	小贴士: 在 systemctl 参数中添加 -H &lt;用户名&gt;@&lt;主机名&gt; 可以实现对其他机器的远程控制。该过程使用ssh链接。
</p></blockquote>
<p>
注意: systemadm 是 systemd 的官方图形前端。</p>
<p><strong>分析系统状态</strong><br />
输出激活的单元：</p>
<pre class="prettyprint lang-bsh">$ systemctl</pre>
<p>
以下命令等效：</p>
<pre class="prettyprint lang-bsh">$ systemctl list-units</pre>
<p>
输出运行失败的单元：</p>
<pre class="prettyprint lang-bsh">$ systemctl --failed</pre>
<p>
所有可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录（后者优先级更高）。查看所有已安装服务：</p>
<pre class="prettyprint lang-bsh">$ systemctl list-unit-files</pre>
<p>
<strong>使用单元</strong><br />
一个单元配置文件可以描述如下内容之一：系统服务（.service）、挂载点（.mount）、sockets（.sockets 、系统设备、交换分区/文件、启动目标（target）、文件系统路径、由 systemd 管理的计时器。详情参阅 man 5 systemd.unit.</p>
<p>使用 systemctl 控制单元时，通常需要使用单元文件的全名，包括扩展名（例如 sshd.service）。但是有些单元可以在systemctl中使用简写方式。</p>
<ul>
<li>
		如果无扩展名，systemctl 默认把扩展名当作 .service。例如 netcfg 和 netcfg.service 是等价的。
	</li>
<li>
		挂载点会自动转化为相应的 .mount 单元。例如 /home 等价于 home.mount。
	</li>
<li>
		设备会自动转化为相应的 .device 单元，所以 /dev/sda2 等价于 dev-sda2.device。
	</li>
</ul>
<p>
立即激活单元：</p>
<pre class="prettyprint lang-bsh"># systemctl start &lt;单元&gt;</pre>
<p>
立即停止单元：</p>
<pre class="prettyprint lang-bsh"># systemctl stop &lt;单元&gt;</pre>
<p>
重启单元：</p>
<pre class="prettyprint lang-bsh"># systemctl restart &lt;单元&gt;</pre>
<p>
命令单元重新读取配置：</p>
<pre class="prettyprint lang-bsh"># systemctl reload &lt;单元&gt;</pre>
<p>
输出单元运行状态：</p>
<pre class="prettyprint lang-bsh">$ systemctl status &lt;单元&gt;</pre>
<p>
检查单元是否配置为自动启动：</p>
<pre class="prettyprint lang-bsh">$ systemctl is-enabled &lt;单元&gt;</pre>
<p>
开机自动激活单元：</p>
<pre class="prettyprint lang-bsh"># systemctl enable &lt;单元&gt;</pre>
<p>
注意: 如果服务没有Install段落，一般意味着应该通过其它服务自动调用它们。如果真的需要手动安装，可以直接连接服务，如下（将foo替换为真实的服务名）：</p>
<pre class="prettyprint lang-bsh"># ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/</pre>
<p>
取消开机自动激活单元：</p>
<pre class="prettyprint lang-bsh"># systemctl disable &lt;单元&gt;</pre>
<p>
显示单元的手册页（必须由单元文件提供）：</p>
<pre class="prettyprint lang-bsh"># systemctl help &lt;单元&gt;</pre>
<p>
重新载入 systemd，扫描新的或有变动的单元：</p>
<pre class="prettyprint lang-bsh"># systemctl daemon-reload</pre>
<p>
<strong>电源管理</strong><br />
安装 polkit 后才可使用电源管理。</p>
<p>如果你正登录在一个本地的systemd-logind用户会话，且当前没有其它活动的会话，那么以下命令无需root权限即可执行。否则（例如，当前有另一个用户登录在某个tty），systemd 将会自动请求输入root密码。</p>
<p>重启：</p>
<pre class="prettyprint lang-bsh">$ systemctl reboot</pre>
<p>
退出系统并停止电源：</p>
<pre class="prettyprint lang-bsh">$ systemctl poweroff</pre>
<p>
待机：</p>
<pre class="prettyprint lang-bsh">$ systemctl suspend</pre>
<p>
休眠：</p>
<pre class="prettyprint lang-bsh">$ systemctl hibernate</pre>
<p>
混合休眠模式（同时休眠到硬盘并待机）：</p>
<pre class="prettyprint lang-bsh">$ systemctl hybrid-sleep</pre>
<p>
<strong><span style="color:#006600;"> 原生 systemd 配置文件</span></strong></p>
<blockquote><p>
	注意: 可能需要手动创建某些文件。所有文件的权限都是644，属主 root，属组 root。
</p></blockquote>
<p><strong>虚拟控制台</strong><br />
可以用/etc/vconsole.conf 文件或者localectl 配置虚拟控制台，包括键盘布局和控制台字体。详情请访问 控制台字体 和 键盘布局。</p>
<p><strong>硬件时钟</strong><br />
systemd 默认硬件时钟为协调世界时（UTC）。</p>
<blockquote><p>
	小贴士: 推荐使用NTP服务来在线同步硬件时钟。
</p></blockquote>
<p>
硬件时钟设定为地方时<br />
将硬件时钟配置为地方时（不建议）：</p>
<pre class="prettyprint lang-bsh"># timedatectl set-local-rtc true</pre>
<p>
重新调整为 UTC：</p>
<pre class="prettyprint lang-bsh"># timedatectl set-local-rtc false</pre>
<p>
如果设置成本地时间，处理夏令时有些麻烦。如果夏令时调整发生在关机时，下次启动时时间会出现问题。最新的内核直接从实时时钟芯片（RTC）读取时间，不使用 hwclock，内核把从 RTC 读取的时间当作 UTC 处理。所以如果硬件时间是地方时，系统启动一开始识别的时间是错误的，之后很快会进行矫正。这可能导致一些问题（尤其是时间倒退时）。</p>
<p>如果同时安装了 Windows 操作系统（默认使用地方时），那么一般 RTC 会被设置为地方时。Windows 其实也能处理 UTC，需要修改注册表。建议让 Windows 使用 UTC，而非让 Linux 使用地方时。Windows 使用 UTC 后，请记得禁用 Windows 的时间同步功能，以防 Windows 错误设置硬件时间。如上文所说，Linux 可以使用NTP服务来在线同步硬件时钟。</p>
<p><strong>内核模块</strong><br />
请访问<a target="_blank" href="https://wiki.archlinux.org/index.php/Kernel_modules_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)">Kernel modules</a></p>
<p><strong>文件系统挂载</strong><br />
默认行为是：在启动一个需要挂载特定分区的服务之前，系统自动检查并挂载分区。/etc/fstab 中设定的网络文件系统（如 NFS、Samba）无需配置即可正常工作，systemd 将确保网络文件系统在网络链接就绪后挂载。</p>
<p>详情参阅：man 5 systemd.mount。</p>
<p>LVM<br />
如果装有不通过 initramfs 激活的LVM卷，则需启动 lvm-monitoring 服务（由 lvm2 软件包提供）：</p>
<pre class="prettyprint lang-bsh"># systemctl enable lvm-monitoring</pre>
<p>
<strong> ACPI 电源管理</strong><br />
参阅 <a target="_blank" href="https://wiki.archlinux.org/index.php/Power_Management_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)">Power Management</a></p>
<p><strong>临时文件</strong><br />
/usr/lib/tmpfiles.d/ 和 /etc/tmpfiles.d/ 中的文件描述了 systemd-tmpfiles 如何创建、清理、删除临时文件和目录，这些文件和目录通常存放在 /run 和 /tmp 中。配置文件名称为 /etc/tmpfiles.d/&lt;program&gt;.conf。此处的配置能覆盖 /usr/lib/tmpfiles.d/ 目录中的同名配置。</p>
<p>临时文件通常和服务文件同时提供，以生成守护进程需要的文件和目录。例如 Samba 服务需要目录 /run/samba 存在并设置正确的权限位，就象这样：</p>
<pre class="prettyprint lang-bsh">/usr/lib/tmpfiles.d/samba.conf
D /run/samba 0755 root root</pre>
<p>
此外，临时文件还可以用来在开机时向特定文件写入某些内容。比如，要禁止系统从USB设备唤醒，利用旧的 /etc/rc.local 可以用 echo USBE &gt; /proc/acpi/wakeup，而现在可以这么做：</p>
<pre class="prettyprint lang-bsh">/etc/tmpfiles.d/disable-usb-wake.conf
w /proc/acpi/wakeup - - - - USBE</pre>
<p>
详情参见 man 5 tmpfiles.d。</p>
<blockquote><p>
	注意: 该方法不能向 /sys 中的配置文件添加参数，因为 systemd-tmpfiles-setup 有可能在相关模块加载前运行。这种情况下，需要首先通过 modinfo &lt;模块名&gt; 确认需要的参数，并在 /etc/modprobe.d 下的一个文件中设置改参数。另外，还可以使用 udev 规则，在设备就绪时设置相应属性。
</p></blockquote>
<p>
<strong><span style="color:#006600;">自己编写 .service 文件</span></strong><br />
systemd 的单元文件是受 XDG Desktop Entry .desktop 文件启发而产生，而最初起源是 Windows 下的 .ini 文件。</p>
<p><strong>处理依赖关系</strong><br />
使用systemd时，可通过正确编写单元配置文件来解决其依赖关系。典型的情况是，单元A要求单元B在A启动之前运行。在此情况下，向单元A配置文件中的 [Unit] 段添加 Requires=B 和 After=B 即可。若此依赖关系是可选的，可添加 Wants=B 和 After=B。请注意 Wants= 和 Requires= 并不意味着 After=，即如果 After= 选项没有制定，这两个单元将被并行启动。</p>
<p>依赖关系通常被用在服务（service）而不是目标（target）上。例如， network.target 一般会被某个配置网络接口的服务引入，所以，将自定义的单元排在该服务之后即可，因为 network.target 已经启动。</p>
<p><strong>启动方式</strong><br />
编写自定义的service文件时，可以选择几种不同的服务启动方式。启动方式可通过配置文件 [Service] 段中的 Type= 参数进行设置。具体的参数说明请参阅 man systemd.service 。</p>
<ul>
<li>
		Type=simple（默认值）：systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务，不要使用此类型启动，除非该服务是socket激活型。
	</li>
<li>
		Type=forking：systemd认为当该服务进程fork，且父进程退出后服务启动成功。对于常规的守护进程（daemon），除非你确定此启动方式无法满足需求，使用此类型启动即可。使用此启动类型应同时指定 PIDFile=，以便systemd能够跟踪服务的主进程。
	</li>
<li>
		Type=oneshot：这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes 使得 systemd 在服务进程退出之后仍然认为服务处于激活状态。
	</li>
<li>
		Type=notify：与 Type=simple 相同，但约定服务会在就绪后向 systemd 发送一个信号。这一通知的实现由 libsystemd-daemon.so 提供。
	</li>
<li>
		Type=dbus：若以此方式启动，当指定的 BusName 出现在DBus系统总线上时，systemd认为服务就绪。
	</li>
</ul>
<p>
<strong>修改现存单元文件</strong><br />
要更改由软件包提供的单元文件，先创建名为 /etc/systemd/system/&lt;单元名&gt;.d/ 的目录（如 /etc/systemd/system/httpd.service.d/），然后放入 *.conf 文件，其中可以添加或重置参数。这里设置的参数优先级高于原来的单元文件。例如，如果想添加一个额外的依赖，创建这么一个文件即可：</p>
<pre class="prettyprint lang-bsh">/etc/systemd/system/&lt;unit&gt;.d/customdependency.conf

[Unit]
Requires=&lt;新依赖&gt;
After=&lt;新依赖&gt;</pre>
<p>
然后运行以下命令使更改生效：</p>
<pre class="prettyprint lang-bsh"># systemctl daemon-reload
# systemctl restart &lt;单元&gt;</pre>
<p>
此外，把旧的单元文件从 /usr/lib/systemd/system/ 复制到 /etc/systemd/system/，然后进行修改，也可以达到同样效果。在 /etc/systemd/system/ 目录中的单元文件的优先级总是高于 /usr/lib/systemd/system/ 目录中的同名单元文件。注意，当 /usr/lib/ 中的单元文件因软件包升级变更时，/etc/ 中自定义的单元文件不会同步更新。此外，你还得执行 systemctl reenable &lt;unit&gt;，手动重新启用该单元。因此，建议使用前面一种利用 *.conf 的方法。</p>
<blockquote><p>
	小贴士: 可以用 systemd-delta 命令来查看哪些单元文件被覆盖、哪些被修改。
</p></blockquote>
<p><strong>单元配置文件的 vim 语法高亮支持</strong><br />
可从官方仓库安装 vim-systemd 软件包，使 unit 配置文件在 Vim 下支持语法高亮。</p>
<p><strong><span style="color:#006600;"> 目标（target）</span></strong><br />
启动级别（runlevel）是一个旧的概念。现在，systemd 引入了一个和启动级别功能相似又不同的概念——目标（target）。不像数字表示的启动级别，每个目标都有名字和独特的功能，并且能同时启用多个。一些目标继承其他目标的服务，并启动新服务。systemd 提供了一些模仿 sysvinit 启动级别的目标，仍可以使用旧的 telinit 启动级别 命令切换。<br />
获取当前目标</p>
<p>不要使用 runlevel 命令了：</p>
<pre class="prettyprint lang-bsh">$ systemctl list-units --type=target</pre>
<p>
<strong>创建新目标</strong><br />
在 Fedora 中，启动级别 0、1、3、5、6 都被赋予特定用途，并且都对应一个 systemd 的目标。然而，没有什么很好的移植用户定义的启动级别（2、4）的方法。要实现类似功能，可以以原有的启动级别为基础，创建一个新的目标 /etc/systemd/system/&lt;新目标&gt;（可以参考 /usr/lib/systemd/system/graphical.target），创建 /etc/systemd/system/&lt;新目标&gt;.wants 目录，向其中加入额外服务的链接（指向 /usr/lib/systemd/system/ 中的单元文件）。</p>
<p><strong>目标表</strong></p>
<table border="1">
<tbody>
<tr>
<th>
				SysV 启动级别
			</th>
<th>
				Systemd 目标
			</th>
<th>
				注释
			</th>
</tr>
<tr>
<td>
				0
			</td>
<td>
				runlevel0.target, poweroff.target
			</td>
<td>
				中断系统（halt）
			</td>
</tr>
<tr>
<td>
				1, s, single
			</td>
<td>
				runlevel1.target, rescue.target
			</td>
<td>
				单用户模式
			</td>
</tr>
<tr>
<td>
				2, 4
			</td>
<td>
				runlevel2.target, runlevel4.target, multi-user.target
			</td>
<td>
				用户自定义启动级别，通常识别为级别3。
			</td>
</tr>
<tr>
<td>
				3
			</td>
<td>
				runlevel3.target, multi-user.target
			</td>
<td>
				多用户，无图形界面。用户可以通过终端或网络登录。
			</td>
</tr>
<tr>
<td>
				5
			</td>
<td>
				runlevel5.target, graphical.target
			</td>
<td>
				多用户，图形界面。继承级别3的服务，并启动图形界面服务。
			</td>
</tr>
<tr>
<td>
				6
			</td>
<td>
				runlevel6.target, reboot.target
			</td>
<td>
				重启
			</td>
</tr>
<tr>
<td>
				emergency
			</td>
<td>
				emergency.target
			</td>
<td>
				急救模式（Emergency shell）
			</td>
</tr>
</tbody>
</table>
<p>
<strong> 切换启动级别/目标</strong><br />
systemd 中，启动级别通过“目标单元”访问。通过如下命令切换：</p>
<pre class="prettyprint lang-bsh"># systemctl isolate graphical.target</pre>
<p>
该命令对下次启动无影响。等价于telinit 3 或 telinit 5。</p>
<p><strong> 修改默认启动级别/目标</strong><br />
开机启动进的目标是 default.target，默认链接到 graphical.target （大致相当于原来的启动级别5）。可以通过内核参数更改默认启动级别：</p>
<blockquote><p>
	小贴士: 可以省略扩展名 .target。
</p></blockquote>
<ul>
<li>
		&nbsp;systemd.unit=multi-user.target （大致相当于级别3）
	</li>
<li>
		&nbsp;systemd.unit=rescue.target （大致相当于级别1）
	</li>
</ul>
<p>
另一个方法是修改 default.target。可以通过 systemctl 修改它：</p>
<pre class="prettyprint lang-bsh"># systemctl enable multi-user.target</pre>
<p>
命令执行情况由 systemctl 显示：链接 /etc/systemd/system/default.target 被创建，指向新的默认启动级别。该方法当且仅当目标配置文件中有以下内容时有效：</p>
<pre class="prettyprint lang-bsh">[Install]
Alias=default.target</pre>
<p>目前，multi-user.target、graphical.target 都包含这段内容。</p>
<p><strong><span style="color:#006600;">日志</span></strong><br />
systemd提供了自己日志系统（logging system），称为 journal. 使用 systemd 日志，无需额外安装日志服务（syslog）。读取日志的命令：</p>
<pre class="prettyprint lang-bsh"># journalctl</pre>
<p>默认情况下（当 Storage= 在文件 /etc/systemd/journald.conf 中被设置为 auto），日志记录将被写入 /var/log/journal/。该目录是 systemd 软件包的一部分。若被删除，systemd 不会自动创建它，直到下次升级软件包时重建该目录。如果该目录缺失，systemd 会将日志记录写入 /run/systemd/journal。这意味着，系统重启后日志将丢失。</p>
<p><strong>过滤输出</strong><br />
journalctl可以根据特定字段过滤输出，例如：</p>
<p>显示本次启动后的所有日志：</p>
<pre class="prettyprint lang-bsh"># journalctl -b</pre>
<p>
不过，一般大家更关心的不是本次启动后的日志，而是上次启动时的（例如，刚刚系统崩溃了）。目前还没有这项功能，正在 systemd-devel@lists.freedesktop.org 讨论中。</p>
<p>目前的折中方案是：</p>
<pre class="prettyprint lang-bsh"># journalctl --since=today | tac | sed -n '/-- Reboot --/{n;:r;/-- Reboot --/q;p;n;b r}' | tac</pre>
<p>以上命令输出本日内的所有启动信息。但要注意，如果日志很多，该命令执行时间会比较漫长。</p>
<p>动态跟踪最新信息：</p>
<pre class="prettyprint lang-bsh"># journalctl -f</pre>
<p>
显示特定程序的所有消息:</p>
<pre class="prettyprint lang-bsh"> # journalctl /usr/lib/systemd/systemd</pre>
<p>
显示特定进程的所有消息:</p>
<pre class="prettyprint lang-bsh"># journalctl _PID=1</pre>
<p>
显示指定单元的所有消息：</p>
<pre class="prettyprint lang-bsh"># journalctl -u netcfg</pre>
<p>
详情参阅man journalctl、man systemd.journal-fields</p>
<p><strong>日志大小限制</strong><br />
如果按上面的操作保留日志的话，默认日志最大限制为所在文件系统容量的 10%，即：如果 /var/log/journal 储存在 50GiB 的根分区中，那么日志最多存储 5GiB 数据。可以修改 /etc/systemd/journald.conf 中的 SystemMaxUse 来指定该最大限制。如限制日志最大 50MiB：</p>
<pre class="prettyprint lang-bsh">SystemMaxUse=50M</pre>
<p>详情参见 man journald.conf.</p>
<p><strong> 配合syslog使用</strong><br />
systemd提供了 socket /run/systemd/journal/syslog，以兼容传统日志服务。所有系统信息都会被传入。要使传统日志服务工作，需要让服务链接该 socket，而非 /dev/log（官方说明）。Arch 软件仓库中的 syslog-ng 已经包含了需要的配置。</p>
<p>设置开机启动 syslog-ng：</p>
<pre class="prettyprint lang-bsh"> # systemctl enable syslog-ng</pre>
<p>
<strong><span style="color:#006600;">疑难解答</span></strong><br />
<strong> 关机/重启十分缓慢</strong><br />
如果关机特别慢（甚至跟死机了一样），很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间，然后再尝试杀死它。请阅读这篇文章，确认你是否是该问题受害者。</p>
<p><strong>短时进程无日志记录</strong><br />
若 journalctl -u foounit.service 没有显示某个短时进程的任何输出，那么改用 PID 试试。例如，若 systemd-modules-load.service 执行失败，那么先用 systemctl status systemd-modules-load 查询其 PID（比如是123），然后检索该 PID 相关的日志 journalctl -b _PID=123。运行时进程的日志元数据（诸如 _SYSTEMD_UNIT 和 _COMM）被乱序收集在 /proc 目录。要修复该问题，必须修改内核，使其通过套接字连接来提供上述数据，该过程类似于 SCM_CREDENTIALS。</p>
<p><strong>诊断启动问题</strong><br />
使用如下内核参数引导： systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M</p>
<p><strong>禁止在程序崩溃时转储内存</strong><br />
要使用老的内核转储，创建下面文件:</p>
<pre class="prettyprint lang-bsh">/etc/sysctl.d/49-coredump.conf

kernel.core_pattern = core
kernel.core_uses_pid = 0</pre>
<p>
然后运行：</p>
<pre class="prettyprint lang-bsh"># /usr/lib/systemd/systemd-sysctl</pre>
<p>
同样可能需要执行“unlimit”设置文件大小：</p>
<pre class="prettyprint lang-bsh">$ ulimit -c unlimited</pre>
<p>
转自：https://wiki.archlinux.org/index.php/systemd_(简体中文)</p>
<div align="right">
	<strong>Sun Jul 20 23:00:16 CST 2014</strong>
</div>

	
